# -*- coding: utf-8 -*-
import random
import string
import json
from datetime import datetime
import os
import requests
from shapely.wkt import loads
import utm
import reverse_geocoder as rg


def get_config(profile, parameter):  # 返回配置文件中的信息
    # 构建完整路径
    json_path = 'Config/{profile}.json'.format(profile=profile)  # 获得文件相对路径
    join_path = get_path(os.path.abspath(__file__), 2, json_path)
    with open(join_path, 'r', encoding="utf-8") as file:
        config = json.load(file)
    return config[parameter]


def get_current_time():  # 返回当前时间
    now_time = datetime.now()
    format_time = now_time.strftime("%Y-%m-%d %H:%M:%S")  # 格式化输出，精确到秒
    return format_time


def get_path(abspath, level, relpath):  # 返回路径
    path = os.path.join(abspath)
    for _ in range(level):  # 向上跳转几级目录至根目录
        path = os.path.dirname(path)

    path = os.path.join(path, relpath)
    return path


def get_transform_coords(is_utm, x, y):  # 进行UTM-50和WGS84坐标系转换
    if is_utm:
        zone_number = 50
        zone_letter = 'R'
        latlon_coords = utm.to_latlon(x, y, zone_number, zone_letter)
        return latlon_coords
    else:
        utm_coords = utm.from_latlon(x, y)  # latitude, longitude
        return utm_coords[:2]  # UTM easting, UTM northing


def get_polyline_bbox(coordinates):
    min_longitude = float('inf')
    min_latitude = float('inf')
    max_longitude = float('-inf')
    max_latitude = float('-inf')

    sets_of_coordinates = coordinates.split('|')

    for set_coords in sets_of_coordinates:
        coords_list = set_coords.split(';')
        for coord in coords_list:
            lon, lat = map(float, coord.split(','))
            min_longitude = min(min_longitude, lon)
            min_latitude = min(min_latitude, lat)
            max_longitude = max(max_longitude, lon)
            max_latitude = max(max_latitude, lat)

    return min_longitude, min_latitude, max_longitude, max_latitude


def get_spatial(address, return_bbox=True):  # 获得具体地点的经纬度坐标或地理围栏
    if return_bbox:  # 返回地理围栏
        url = "https://restapi.amap.com/v3/config/district"
        ak = get_config('config', 'gaode_api_key')["app"]
        params = {
            "keywords": address,
            "subdistrict": "0",
            "extensions": "all",
            "key": ak
        }
        response = requests.get(url=url, params=params)
        if response:
            if response.json()['count'] == "0":
                return -1
            polyline = response.json()['districts'][0]['polyline']

            bbox = get_polyline_bbox(polyline)
            return bbox
    else:  # 返回经纬度坐标
        url = "https://api.map.baidu.com/geocoding/v3"
        ak = get_config('config', 'baidu_api_key')["app"]
        params = {
            "address": address,
            "output": "json",
            "ak": ak
        }
        response = requests.get(url=url, params=params)
        if response:
            if response.json()['status'] == 1:
                return -1
            point = response.json()['result']['location']
            return point


def get_location(address, return_bbox=True):  # 获得具体地点的经纬度坐标或地理围栏
    ak = get_config('config', 'baidu_api_key')["app"]
    array0 = []  # 用于接收边界的坐标
    if return_bbox:  # 返回地理围栏
        url = "https://api.map.baidu.com/api_region_search/v1/"
        params = {
            "keyword": address,
            "boundary": "1",
            "ak": ak
        }
        response = requests.get(url=url, params=params)
        if response:
            if response.json()['result_size'] == 0:
                return -1, array0
            if 'districts' not in response.json()['districts'][0]:
                return -1, array0
            if 'polyline' not in response.json()['districts'][0]:
                return -1, array0
            polyline = response.json()['districts'][0]['polyline']
            polygon = loads(polyline)
            b = str(polygon.boundary)
            if b[0] == 'M':
                boundary = b[18:-2:]
            else:
                boundary = b[12:-1:]
            arr = boundary.split("), (")
            length = 0
            a = 0
            for i in range(0, len(arr)):
                item = arr[i].split(', ')
                if len(item) > length:
                    length = len(item)
                    a = i
            item = arr[a].split(', ')
            array0 = []
            for item0 in item:
                zuobiao = item0.split(' ')
                array0.append(zuobiao)
            bbox = polygon.bounds
            return bbox, array0
    else:  # 返回经纬度坐标
        url = "https://api.map.baidu.com/geocoding/v3"
        params = {
            "address": address,
            "output": "json",
            "ak": ak
        }
        response = requests.get(url=url, params=params)
        if response.json()['status'] == 0:
            print(response.json()['result'])
        if response:
            if response.json()['status'] == 1:
                return -1, array0
            if response.json()['result']['confidence'] > 70:
                return -1, array0
            point = response.json()['result']['location']
            return point, array0


def get_province_name(latitude, longitude):
    province_map = {
        "Anhui Sheng": "安徽省",
        "Beijing": "北京市",
        "Chongqing Shi": "重庆市",
        "Fukien": "福建省",
        "Fujian": "福建省",
        "Gansu Sheng": "甘肃省",
        "Guangdong": "广东省",
        "Guangxi Zhuangzu Zizhiqu": "广西自治区",
        "Guizhou Sheng": "贵州省",
        "Hainan": "海南省",
        "Hebei": "河北省",
        "Heilongjiang Sheng": "黑龙江省",
        "Henan Sheng": "河南省",
        "Hubei": "湖北省",
        "Hunan": "湖南省",
        "Inner Mongolia": "内蒙古自治区",
        "Jiangsu Sheng": "江苏省",
        "Jiangxi Sheng": "江西省",
        "Jilin Sheng": "吉林省",
        "Liaoning": "辽宁省",
        "Ningxia Huizu Zizhiqu": "宁夏自治区",
        "Qinghai Sheng": "青海省",
        "Shaanxi": "陕西省",
        "Shandong Sheng": "山东省",
        "Shanghai Shi": "上海市",
        "Shanxi Sheng": "山西省",
        "Sichuan": "四川省",
        "Kaohsiung": "台湾省",
        "Taipei": "台湾省",
        "Taiwan": "台湾省",
        "Tianjin Shi": "天津市",
        "Tibet Autonomous Region": "西藏自治区",
        "Xinjiang Uygur Zizhiqu": "新疆自治区",
        "Yunnan": "云南省",
        "Zhejiang Sheng": "浙江省",
        "Kowloon City": "香港特别行政区",
        "Macau": "澳门特别行政区"
    }

    coordinates = (latitude, longitude)
    result = rg.search(coordinates, mode=1)

    # 提取省级信息
    province = result[0]['admin1']
    if province in province_map:
        province = province_map[province]

    return province


def get_address(location_list):  # 输入一个坐标列表或者坐标进行逆地址转换
    if len(location_list) == 1:
        ak = get_config('config', 'baidu_api_key')["app"]
        url = "https://api.map.baidu.com/reverse_geocoding/v3/"
        params = {
            "location": "{lat},{lng}".format(lat=location_list[0][1], lng=location_list[0][0]),
            "output": "json",
            "coordtype": "wgs84",
            "extensions_poi": "0",
            "ak": ak
        }
        response = requests.get(url=url, params=params)
        return response.json()['result']["formatted_address"]
    else:
        address = set()
        for location in location_list:
            address.add(get_province_name(location[1], location[0]))
        address_list = sorted(list(address))
        address_list = [address for address in address_list if address != ""]
        if len(address_list) == 1:
            return address_list[0]
        else:
            return ','.join(map(str, address_list))


def get_dataset(image_name):  # 通过景号获取图片数据集
    data_list = get_config("data", "DATASET")
    data_initial = image_name.split("_")[0]
    for dataset in data_list:
        scene_initial = get_config("data", dataset)["scene_initial"]
        if image_name.startswith(scene_initial):
            return dataset
    return "TASK"


def get_image(image_type, image_name):  # image_type 标识数据类型: quick_look、available、download、task_data、 分别对应浏览图、原始数据、结果数据
    dataset = get_dataset(image_name)
    if dataset == 'TASK':
        return get_path(os.path.abspath(__file__), 2, get_config("data", "TASK")['result_path'])
    else:
        if image_type == "quick_look":
            return os.path.join(get_path(os.path.abspath(__file__), 2, get_config("data", dataset)['quicklook_path']),
                                image_name + ".png")
        if image_type == "available":
            return os.path.join(get_path(os.path.abspath(__file__), 2, get_config("data", dataset)['available_path']),
                                image_name + ".TIFF")
